# -*- coding: utf-8 -*-
import scrapy
from scrapy import signals
from scrapy.http import Request
import mysql.connector
from mysql.connector import errorcode
from mysql.connector.errors import Error
from urllib.parse import quote
import json

from qqmusic.items import AlbumItem

class AlbumSpider(scrapy.Spider):
    name = 'album'
    allowed_domains = ['y.qq.com']
    start_urls = ['https://u.y.qq.com/cgi-bin/musicu.fcg']
    headers = {
        'Content-Type': 'application/json',
        "accept": "application/json",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
    }

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = cls(*args, **kwargs)
        spider._set_crawler(crawler)
        crawler.signals.connect(spider.engine_started, signal=signals.engine_started)
        crawler.signals.connect(spider.engine_stoped, signal=signals.engine_stopped)
        return spider
        pass

    def engine_started(self):
        try:
            self.connection = mysql.connector.connect(user="root", password="", host="localhost", database="db_music")
            self.cursor = self.connection.cursor()
        except Error as err:
            if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
                print("Something is wrong with your user name or password")
            elif err.errno == errorcode.ER_BAD_DB_ERROR:
                print("Database does not exist")
            else:
                print(err)
        pass

    def engine_stoped(self):
        if self.connection is not None:
            try:
                self.cursor.close()
                self.connection.close()
            except Exception as e:
                print(e)
        pass

    def parse(self, response):
        data = json.loads(response.text)
        assert data['code'] == 0 and data['getAlbumList']['code'] == 0, "Code is not 0 (%s)" % (data['code'])

        data = data['getAlbumList']['data']
        album_list = data['albumList']
        for album in album_list:
            item = AlbumItem()
            item['album_qqmusic_singer_mid'] = data['singerMid']
            item['album_mid'] = album['albumMid']
            item['album_id'] = album['albumID']
            item['album_name'] = album['albumName']
            item['album_trans_name'] = album['albumTranName']
            item['publish_date'] = album['publishDate']
            item['pmid'] = album['pmid']
            item['album_type'] = album['albumType']
            item['singer_name'] = album['singerName']
            yield item
            pass
        pass

    def start_requests(self):
        for url in self.start_urls:
            # 为每一个歌手查询他的所有专辑

            query_sql = "SELECT `qqmusic_singer_mid`, `qqmusic_singer_id` FROM `tb_singer` LIMIT {}, 10"
            offset_tb = 0
            while True:
                self.cursor.execute(query_sql.format(offset_tb))
                res_count = 0

                for (singer_mid, singer_id) in self.cursor:
                    res_count += 1
                    args = {"singer_mid": singer_mid, "singer_id": singer_id}
                    cur_url = AlbumSpider.build_url(url, args)
                    yield Request(cur_url, callback=self.parse, method="GET", headers=self.headers, dont_filter=True)
                    pass

                if res_count == 0:
                    break

                offset_tb += res_count
                pass
        pass

    @staticmethod
    def build_url(base_url, args):
        """
        构造专辑url
        -: getAlbumList5526497438066191
        g_tk: 5381
        loginUin: 0
        hostUin: 0
        format: json
        inCharset: utf8
        outCharset: utf-8
        notice: 0
        platform: yqq.json
        needNewCode: 0
        data: {"comm":{"ct":24,"cv":0},"getAlbumList":{"method":"GetAlbumList","param":{"singerMid":"0025NhlN2yWrP4","order":0,"begin":0,"num":5,"songNumTag":0,"singerID":0},"module":"music.musichallAlbum.AlbumListServer"}}
        """
        url = base_url + "?"

        fixed_options = {
            "-": "getAlbumList5526497438066191",
            "g_tk": 5381,
            "loginUin": 0,
            "hostUin": 0,
            "format": "json",
            "inCharset": "utf8",
            "outCharset": "utf-8",
            "notice": 0,
            "platform": "yqq.json",
            "needNewCode": 0,
            "data": ''  # 由 fixed_data_params 进行 url_decode 得到
        }

        fixed_data_params = {
            "comm": {
                "ct": 24,
                "cv": 0
            },
            "getAlbumList": {
                "method": "GetAlbumList",
                "param": {
                    "singerMid": args['singer_mid'],
                    "order": 0,
                    "begin": 0,
                    "num": -1,  # 选择全部的专辑
                    "songNumTag": 0,
                    "singerID": args['singer_id']
                },
                "module": "music.musichallAlbum.AlbumListServer"
            }
        }

        fixed_options['data'] = quote(json.dumps(fixed_data_params, separators=(",", ":")))

        for k, v in fixed_options.items():
            url += str(k) + "=" + str(v) + "&"
            pass

        return url
        pass



"""
https://u.y.qq.com/cgi-bin/musicu.fcg?-=getAlbumList5526497438066191&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22getAlbumList%22%3A%7B%22method%22%3A%22GetAlbumList%22%2C%22param%22%3A%7B%22singerMid%22%3A%220025NhlN2yWrP4%22%2C%22order%22%3A0%2C%22begin%22%3A0%2C%22num%22%3A5%2C%22songNumTag%22%3A0%2C%22singerID%22%3A0%7D%2C%22module%22%3A%22music.musichallAlbum.AlbumListServer%22%7D%7D
"""
